package com.xd.core.note.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Lists;
import com.xd.common.constant.SysConstant;
import com.xd.core.note.ICacheService;
import com.xd.core.system.entity.CityInfo;
import com.xd.core.system.entity.Dictionary;
import com.xd.core.system.entity.ProvincesInfo;
import com.xd.core.system.entity.SysPermission;
import com.xd.core.system.mapper.SysPermissionMapper;
import com.xd.core.system.service.ICityInfoService;
import com.xd.core.system.service.IDictionaryService;
import com.xd.core.system.service.IProvincesInfoService;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CacheServiceImpl implements ICacheService {

    private static final String DICTIONARY = "D_";

    @Resource
    private ICityInfoService cityInfoService;

    @Resource
    private IProvincesInfoService iProvincesInfoService;
    @Resource
    private IDictionaryService dictionaryService;
    @Resource
    private SysPermissionMapper sysPermissionMapper;

    @Override
    @Cacheable(cacheNames = "city#30")
    public List<CityInfo> city() {
        return cityInfoService.list(null);
    }

    @Override
    @Cacheable(cacheNames = "city#30", key = "#head")
    public List<CityInfo> city(boolean head) {
        List<CityInfo> cityTree = new ArrayList<>();
        Map<Integer, CityInfo> cityMap = new HashMap<>();
        List<CityInfo> cityInfos = cityInfoService.list(head ? null : new LambdaQueryWrapper<CityInfo>().ne(CityInfo::getId, SysConstant.CRM_CITY_NATION_WIDE_ID));
        for (CityInfo cityInfo : cityInfos) {
            cityMap.put(cityInfo.getId(), cityInfo);
            CityInfo parent = cityMap.get(cityInfo.getPid());
            if (parent != null) {
                parent.addChild(cityInfo);
            } else {
                cityTree.add(cityInfo);
            }
        }
        return cityTree;
    }
    @Override
    @Cacheable(cacheNames = "province#30", key = "#head")
    public List<ProvincesInfo> province(boolean head) {
        List<ProvincesInfo> provinceTree = new ArrayList<>();
        Map<Integer, ProvincesInfo> cityMap = new HashMap<>();
        List<ProvincesInfo> provincesInfos = iProvincesInfoService.list(head ? null : new LambdaQueryWrapper<ProvincesInfo>().ne(ProvincesInfo::getId, SysConstant.CRM_PROVINCE_NATION_WIDE_ID));
        for (ProvincesInfo provincesInfo : provincesInfos) {
            cityMap.put(provincesInfo.getId(), provincesInfo);
            ProvincesInfo parent = cityMap.get(provincesInfo.getParentId());
            if (parent != null) {
                parent.addChild(provincesInfo);
            } else {
                provinceTree.add(provincesInfo);
            }
        }
        return provinceTree;
    }

    @Override
    @Cacheable(cacheNames = "permission#10", key = "#userId")
    public List<SysPermission> selectSysperms(Integer userId) {
        return sysPermissionMapper.selectSysperms(userId, null);
    }

    @Cacheable(cacheNames = "dictionary#30", key = "'Map-'.concat(#type)")
    public LinkedHashMap<String, String> dictionaryMap(String type) {
        return this.dictionaryList(type).stream().collect(Collectors.toMap(Dictionary::getCode, Dictionary::getName, (existing, replacement) -> existing, LinkedHashMap::new));
    }

    @Override
    @Cacheable(cacheNames = "dictionary#30", key = "'List-'.concat(#type)")
    public List<Dictionary> dictionaryList(String type) {
        List<Dictionary> list = dictionaryService.list(new LambdaQueryWrapper<Dictionary>().eq(Dictionary::getType, type).ne(Dictionary::getPid, 0).select(Dictionary::getCode, Dictionary::getName).orderByDesc(Dictionary::getSort));
        boolean f = true;
        for (Dictionary dictionary : list) {
            if (dictionary.getCode().equals("-2")) {
                f = false;
                break;
            }
        }
        if (f) list.add(new Dictionary().setCode("-2").setName("无"));
        return list;
    }




    @Cacheable(cacheNames = "city#30", key = "'IdMaps'")
    public Map<Integer, List<String>> IdMaps() {
        return cityInfoService.list(new LambdaQueryWrapper<CityInfo>().eq(CityInfo::getFlag, SysConstant.XKD_YES)).stream().collect(Collectors.toMap(CityInfo::getId, c -> {
            List<String> arr = Lists.newArrayList();
            arr.add(c.getMapCode());//0mapCode
            arr.add(c.getPid().toString());//1PID
            arr.add(c.getDistrictName());//2xxx不带市
            arr.add(c.getExtName());//3xxx带市
            arr.add(c.getProvinceName());//4xxx省
            return arr;
        }));
    }

    @Cacheable(cacheNames = "city#30", key = "'CodeMaps'")
    public Map<String, List<String>> CodeMaps() {
        return cityInfoService.list(new LambdaQueryWrapper<CityInfo>().eq(CityInfo::getFlag, SysConstant.XKD_YES)).stream().collect(Collectors.toMap(CityInfo::getMapCode, c -> {
            List<String> arr = Lists.newArrayList();
            arr.add(c.getId().toString());//0ID
            arr.add(c.getPid().toString());//1PID
            arr.add(c.getDistrictName());//2xxx市
            arr.add(c.getExtName());//3xxx带市
            arr.add(c.getProvinceName());//4xxx省
            return arr;
        }));
    }

    /**
     * 不带市
     *
     * @return
     */
    @Cacheable(cacheNames = "city#30", key = "'NameMaps'")
    public Map<String, List<String>> NameMaps() {
        return cityInfoService.list(new LambdaQueryWrapper<CityInfo>().eq(CityInfo::getFlag, SysConstant.XKD_YES)).stream().collect(Collectors.toMap(CityInfo::getDistrictName, c -> {
            List<String> arr = Lists.newArrayList();
            arr.add(c.getId().toString());//0ID
            arr.add(c.getPid().toString());//1PID
            arr.add(c.getMapCode());//2mapCode
            arr.add(c.getExtName());//3xxx带市
            arr.add(c.getProvinceName());//4xxx省
            return arr;
        }));
    }

    /**
     * 带市
     *
     * @return
     */
    @Cacheable(cacheNames = "city#30", key = "'ExtNameMaps'")
    public Map<String, List<String>> ExtNameMaps() {
        return cityInfoService.list(new LambdaQueryWrapper<CityInfo>().eq(CityInfo::getFlag, SysConstant.XKD_YES)).stream().collect(Collectors.toMap(CityInfo::getExtName, c -> {
            List<String> arr = Lists.newArrayList();
            arr.add(c.getId().toString());//0ID
            arr.add(c.getPid().toString());//1PID
            arr.add(c.getMapCode());//2mapCode
            arr.add(c.getDistrictName());//3xxx不带市
            arr.add(c.getProvinceName());//4xxx省
            return arr;
        }));
    }

}
